<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>xeokit BIM Viewer</title>
    <link rel="stylesheet" href="./lib/fontawesome-free-5.11.2-web/css/all.min.css" type="text/css" />
    <link rel="stylesheet" href="../dist/xeokit-bim-viewer.css" type="text/css" />
    <link rel="stylesheet" href="./css/style.css" />
</head>

<body>
    <input type="checkbox" id="explorer_toggle" />
    <label for="explorer_toggle" class="xeokit-i18n explorer_toggle_label xeokit-btn fas fa-2x fa-sitemap"
        data-xeokit-i18ntip="toolbar.toggleExplorer" data-tippy-content="Toggle explorer"></label>
    <input type="checkbox" id="inspector_toggle" />
    <label id="inspector_toggle_label" for="inspector_toggle"
        class="xeokit-i18n inspector_toggle_label xeokit-btn fas fa-info-circle fa-2x"
        data-xeokit-i18ntip="toolbar.toggleProperties" data-tippy-content="Toggle properties"></label>
    <div id="myExplorer"></div>
    <div id="myToolbar"></div>
    <div id="myInspector"></div>
    <div id="myViewer">
        <canvas id="myCanvas"></canvas>
        <canvas id="myNavCubeCanvas"></canvas>
    </div>

</body>

<!-- Tooltips libraries -->
<script src="./lib/popper.js"></script>
<script src="./lib/tippy.js"></script>

<script type="module">

    import { Server, BIMViewer, LocaleService } from "../dist/xeokit-bim-viewer.es.js";

    import { messages as localeMessages } from "../dist/messages.js";

    window.onload = function () {

        const requestParams = getRequestParams();
        const locale = requestParams.locale || "en";
        const projectId = requestParams.projectId;

        if (!projectId) {
            return;
        }

        const openExplorer = requestParams.openExplorer;
        setExplorerOpen(openExplorer === "true");

        const enableEditModels = (requestParams.enableEditModels === "true");

        const server = new Server({
            dataDir: requestParams.dataDir || "./data"
        });

        const bimViewer = new BIMViewer(server, {
            localeService: new LocaleService({
                messages: localeMessages,
                locale: locale
            }),
            enableMeasurements: true,
            canvasElement: document.getElementById("myCanvas"), // WebGL canvas
            keyboardEventsElement: document, // Optional, defaults to document
            explorerElement: document.getElementById("myExplorer"), // Left panel
            toolbarElement: document.getElementById("myToolbar"), // Toolbar
            inspectorElement: document.getElementById("myInspector"), // Right panel
            navCubeCanvasElement: document.getElementById("myNavCubeCanvas"),
            busyModelBackdropElement: document.getElementById("myViewer"),
            enableEditModels: enableEditModels
        });

        bimViewer.localeService.on("updated", () => {
            const localizedElements = document.querySelectorAll('.xeokit-i18n');
            localizedElements.forEach((localizedElement) => {
                if (localizedElement.dataset.xeokitI18n) {
                    localizedElement.innerText = bimViewer.localeService.translate(localizedElement.dataset.xeokitI18n);
                }
                if (localizedElement.dataset.xeokitI18ntip) {
                    const translation = bimViewer.localeService.translate(localizedElement.dataset.xeokitI18ntip);
                    if (translation) {
                        localizedElement.dataset.tippyContent = bimViewer.localeService.translate(localizedElement.dataset.xeokitI18ntip);
                    }
                }
                if (localizedElement.dataset.tippyContent) {
                    if (localizedElement._tippy) {
                        localizedElement._tippy.setContent(localizedElement.dataset.tippyContent);
                    } else {
                        tippy(localizedElement, {
                            appendTo: "parent",
                            zIndex: 1000000,
                            allowHTML: true
                        });
                    }
                }
            });
        });

        bimViewer.setConfigs({
            "showSpaces": false, // Default
            "selectedGlowThrough": true,
            "highlightGlowThrough": true,
            "dtxEnabled": true // Enable data texture scene representation for models - may be slow on low-spec GPUs
        });

        bimViewer.on("openExplorer", () => {
            setExplorerOpen(true);
        });

        bimViewer.on("openInspector", () => {
            setInspectorOpen(true);
        });

        bimViewer.on("addModel", (event) => { // "Add" selected in Models tab's context menu
            console.log("addModel: " + JSON.stringify(event, null, "\t"));
        });

        bimViewer.on("editModel", (event) => { // "Edit" selected in Models tab's context menu
            console.log("editModel: " + JSON.stringify(event, null, "\t"));
        });

        bimViewer.on("deleteModel", (event) => { // "Delete" selected in Models tab's context menu
            console.log("deleteModel: " + JSON.stringify(event, null, "\t"));
        });

        const viewerConfigs = requestParams.configs;
        if (viewerConfigs) {
            const configNameVals = viewerConfigs.split(",");
            for (let i = 0, len = configNameVals.length; i < len; i++) {
                const configNameValStr = configNameVals[i];
                const configNameVal = configNameValStr.split(":");
                const configName = configNameVal[0];
                const configVal = configNameVal[1];
                bimViewer.setConfig(configName, configVal);
            }
        }

        bimViewer.loadProject(projectId, () => {
            const modelId = requestParams.modelId;
            if (modelId) {
                bimViewer.loadModel(modelId);
            }
            const tab = requestParams.tab;
            if (tab) {
                bimViewer.openTab(tab);
            }
            watchHashParams();
        },
            (errorMsg) => {
                console.error(errorMsg);
            });

        function watchHashParams() {
            let lastHash = "";
            window.setInterval(() => {
                const currentHash = window.location.hash;
                if (currentHash !== lastHash) {
                    parseHashParams();
                    lastHash = currentHash;
                }
            }, 400);
        }

        function parseHashParams() {
            const params = getHashParams();
            const actionsStr = params.actions;
            if (!actionsStr) {
                return;
            }
            const actions = actionsStr.split(",");
            if (actions.length === 0) {
                return;
            }
            for (let i = 0, len = actions.length; i < len; i++) {
                const action = actions[i];
                switch (action) {
                    case "focusObject":
                        const objectId = params.objectId;
                        if (!objectId) {
                            console.error("Param expected for `focusObject` action: 'objectId'");
                            break;
                        }
                        bimViewer.setAllObjectsSelected(false);
                        bimViewer.setObjectsSelected([objectId], true);
                        bimViewer.flyToObject(objectId, () => {
                            // FIXME: Showing objects in tabs involves scrolling the HTML within the tabs - disable until we know how to scroll the correct DOM element. Otherwise, that function works OK

                            // bimViewer.showObjectInObjectsTab(objectId);
                            // bimViewer.showObjectInClassesTab(objectId);
                            // bimViewer.showObjectInStoreysTab(objectId);
                        });
                        break;
                    case "focusObjects":
                        const objectIds = params.objectIds;
                        if (!objectIds) {
                            console.error("Param expected for `focusObjects` action: 'objectIds'");
                            break;
                        }
                        const objectIdArray = objectIds.split(",");
                        bimViewer.setAllObjectsSelected(false);
                        bimViewer.setObjectsSelected(objectIdArray, true);
                        bimViewer.viewFitObjects(objectIdArray, () => {
                        });
                        break;
                    case "clearFocusObjects":
                        bimViewer.setAllObjectsSelected(false);
                        bimViewer.viewFitAll();
                        // TODO: view fit nothing?
                        break;
                    case "openTab":
                        const tabId = params.tabId;
                        if (!tabId) {
                            console.error("Param expected for `openTab` action: 'tabId'");
                            break;
                        }
                        bimViewer.openTab(tabId);
                        break;
                    default:
                        console.error("Action not supported: '" + action + "'");
                        break;
                }
            }
        }

        function setExplorerOpen(explorerOpen) {
            const toggle = document.getElementById("explorer_toggle");
            if (toggle) {
                toggle.checked = explorerOpen;
            }
        }

        function setInspectorOpen(inspectorOpen) {
            const toggle = document.getElementById("inspector_toggle");
            if (toggle) {
                toggle.checked = inspectorOpen;
            }
        }

        function getRequestParams() {
            const vars = {};
            window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, (m, key, value) => {
                vars[key] = value;
            });
            return vars;
        }

        function getHashParams() {
            const hashParams = {};
            let e;
            const a = /\+/g;  // Regex for replacing addition symbol with a space
            const r = /([^&;=]+)=?([^&;]*)/g;
            const d = function (s) {
                return decodeURIComponent(s.replace(a, " "));
            };
            const q = window.location.hash.substring(1);
            while (e = r.exec(q)) {
                hashParams[d(e[1])] = d(e[2]);
            }
            return hashParams;
        }

        window.bimViewer = bimViewer;
    }

</script>

</html>